/**
 * 复制文本
 * @param text
 */
export const copyText = async (text: string) => {
  try {
    await navigator.clipboard.writeText(text);
  } catch (err) {
    let copyText = document.createElement("textarea");
    copyText.style.position = "fixed";
    copyText.style.opacity = "0";
    copyText.value = text;
    document.body.append(copyText);
    copyText.focus();
    copyText.select();
    document.execCommand("copy");
    document.body.removeChild(copyText);
  }
};

/**
 * 获取文件名后缀
 * @param name 文件名
 * @param dot 是否需要间隔点
 * @returns ext | .evt 统一小写
 */
export function getFileExt(fileName: string, dot = false) {
  const mat = fileName.match(/\.([^.]+)$/);
  if (!mat) return "";
  let ext = mat[1].toLowerCase();
  return dot ? "." + ext : ext;
}

//获取音频时长
export async function getAudioDuration(file: File) {
  return new Promise<number>((resolve) => {
    const fileReader = new FileReader();
    fileReader.onload = (event: any) => {
      const audio = new Audio(event.target.result);
      audio.oncanplaythrough = () => {
        resolve(Math.floor(audio.duration));
      };
    };
    fileReader.readAsDataURL(file);
  });
}

//动画函数
export function animation(opt: {
  from: number;
  to: number;
  duration?: number;
  onUpdate?: (val: number) => void;
  onEnd?: () => void;
}) {
  const { from, to, duration = 1000, onUpdate, onEnd } = opt;
  let value = from;
  const start = Date.now();
  // const speed = (to - from) / duration;

  function interpolate(t: number, from: number, to: number, duration: number) {
    // 使用贝塞尔曲线插值
    const p = t / duration;
    return from + (to - from) * (p * (2 - p));
  }

  function _run() {
    const t = Date.now() - start;
    if (t > duration) {
      value = to;
      onUpdate?.(value);
      onEnd?.();
      return;
    }
    // value = from + t * speed;
    value = interpolate(t, from, to, duration);
    onUpdate?.(value);
    requestAnimationFrame(_run);
  }
  requestAnimationFrame(_run);
}

//返回当前dom计算后的css值
export function getStyle(ele: Element, attr: keyof CSSStyleDeclaration) {
  return window.getComputedStyle(ele, null)[attr];
}

//冒泡排序
export function fsrot(arr: number[]) {
  let k = arr.length;
  while (k > 0) {
    for (let i = 0; i < arr.length - 1; i++) {
      //如果相邻第一个数大于第二个数，就替换位置
      if (arr[i] > arr[i + 1]) {
        let temp = arr[i];
        arr[i] = arr[i + 1];
        arr[i + 1] = temp;
      }
    }
    k--;
  }
  return arr;
}

/**
 * 图片文件转base64
 * @param file 图片文件
 * @returns base64 url
 */
export const base64 = (file: File) => {
  return new Promise<string>((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => {
      resolve(reader.result as string);
    };
    reader.onerror = () => {
      reject("读取文件错误");
    };
  });
};

/**
 * 金额转换
 * @param number
 * @returns ¥123,456.79
 */
export const fmtNumber = (number: number) => {
  const china = new Intl.NumberFormat("zh-CN", {
    style: "currency",
    currency: "CNY",
  });
  return china.format(number);
};

/**
 * 假进度
 * @param aFn
 * @param progress
 * @param threshold
 */
export function fProgress(
  aFn: () => Promise<void>,
  progress?: (percent: number) => void,
  threshold = 15 // 增长阈值，值越小速度越大
) {
  let [from, to] = [0, 100];
  let percent = from;
  let frameId: number;

  function _run() {
    percent += (to - percent) / threshold; // 使进度无限接近90%
    percent = Math.min(percent, to);
    progress?.(percent);
    frameId = requestAnimationFrame(_run);
  }
  frameId = requestAnimationFrame(_run);

  aFn()
    .then(() => {
      cancelAnimationFrame(frameId);
      percent = 100;
      progress?.(percent);
    })
    .catch((_) => {
      cancelAnimationFrame(frameId);
    });
}
